package ar.edu.utn.frba.disenio.aterrizar.aerolineas;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.uqbar.commons.model.UserException;

import com.oceanic.AerolineaOceanic;
import com.oceanic.AsientoDTO;
import ar.edu.utn.frba.disenio.aterrizar.busquedas.CriterioBusqueda;
import ar.edu.utn.frba.disenio.aterrizar.excepciones.*;
import ar.edu.utn.frba.disenio.aterrizar.usuario.*;
import ar.edu.utn.frba.disenio.aterrizar.estrategia.*;
import ar.edu.utn.frba.disenio.aterrizar.fechas.Fecha;

public class AdapterOceanic extends Aerolinea{
	
	protected AerolineaOceanic aerolinea;
	protected EstrategiaLugar parserEstrategiaLugar;
	
	public AdapterOceanic(){
		this.aerolinea = AerolineaOceanic.getInstance();
		this.setRecargoAerolinea(1.18);
		this.setParserLugar();
		this.nombreAerolinea = "Oceanic";		
	}
	
	public AdapterOceanic(AerolineaOceanic mock){
		this.aerolinea = mock;
		this.setRecargoAerolinea(1.18);
		this.setParserLugar();
		this.nombreAerolinea = "Oceanic";
	}
		
		
	@Override
	public ArrayList<Vuelo> buscarVuelos(CriterioBusqueda busqueda) {
		
		String lugarOrigen;
		String lugarDestino;
		try{
			lugarOrigen = this.parserEstrategiaLugar.parsearLugar(busqueda.getOrigen()); 
			lugarDestino = this.parserEstrategiaLugar.parsearLugar(busqueda.getDestino());
		}catch(NoSePuedeParsearConNingunaEstrategiaLugarException e){
			throw new UserException("Ingrese un origen y destino valido");
		}
		
		String fecha = busqueda.fecha.convertirAString();
		ArrayList<Vuelo> retVal = new ArrayList<Vuelo>();
		List<AsientoDTO> disponibles = aerolinea.asientosDisponiblesParaOrigenYDestino(lugarOrigen, lugarDestino, fecha);
		for(AsientoDTO otroAsiento : disponibles){
			String [] otroVuelo = this.parsearAsientoDTOAVuelo(otroAsiento);
			Vuelo elOtroVuelo = new Vuelo(otroVuelo);
			if(busqueda.fecha.fechaEstasEntre(elOtroVuelo.fechaSalida, elOtroVuelo.fechaLlegada)){
				elOtroVuelo.setAerolinea(this.nombreAerolinea);
				retVal.add(elOtroVuelo);
			}
		}

		return retVal;
	}
	

	@Override
	public void comprarAsiento(String codigoAsiento, Usuario unUsuario) {

		String [] parserCodigo = codigoAsiento.split("&");
		if(codigoAsiento.length() == parserCodigo[0].length())	{
			String [] vuelo = codigoAsiento.split("-");
			String codigoVuelo = vuelo[0];
			Integer numeroAsiento = Integer.parseInt(vuelo[1]);
			if(!aerolinea.comprarSiHayDisponibilidad(unUsuario.getDni(), codigoVuelo, numeroAsiento)){ 
				throw new AsientoNoDisponibleException();
			}
		} else {
			for (int i = 0; i < parserCodigo.length; i++)	{
					String [] vuelo = parserCodigo[i].split("-");
					String codigoVuelo = vuelo[0];
					Integer numeroAsiento = Integer.parseInt(vuelo[1]);
					if(!aerolinea.comprarSiHayDisponibilidad(unUsuario.getDni(), codigoVuelo, numeroAsiento)){ 
						throw new AsientoNoDisponibleException();
					}
			}
		}
		
	}
	

	@Override
	public void reservar(String codigoAsiento, Usuario usuario){
		
		String [] parserCodigo = codigoAsiento.split("&");
		if(codigoAsiento.length() == parserCodigo[0].length())	{
			String [] parser = codigoAsiento.split("-"); 
			Integer asiento= Integer.parseInt(parser[1]);
			String codigoVuelo= parser[0];
			
			if(!(aerolinea.reservar(usuario.getDni(), codigoVuelo, asiento)))
				throw new AsientoNoDisponibleException(); 
		}else{
			for (int i = 0; i < parserCodigo.length; i++)	{
				String [] parser = parserCodigo[i].split("-"); 
				Integer asiento= Integer.parseInt(parser[1]);
				String codigoVuelo= parser[0];
				
				if(!(aerolinea.reservar(usuario.getDni(), codigoVuelo, asiento)))
					throw new AsientoNoDisponibleException(); 
			}
		}
		
	}
	
	@Override
	public ArrayList<Vuelo> buscarVuelosPorOrigen(String origen, Fecha fechaDeSalida) {
		
		String lugarOrigen  = this.parserEstrategiaLugar.parsearLugar(origen);
			
		String fecha =fechaDeSalida.convertirAString();
		ArrayList<Vuelo> retVal = new ArrayList<Vuelo>();
		List<AsientoDTO> disponibles = aerolinea.asientosDisponiblesParaOrigen(lugarOrigen, fecha);
		for(AsientoDTO otroAsiento : disponibles){
			String [] otroVuelo = this.parsearAsientoDTOAVuelo(otroAsiento);
			Vuelo elOtroVuelo = new Vuelo(otroVuelo);
			if(fechaDeSalida.fechaEstasEntre(elOtroVuelo.fechaSalida, elOtroVuelo.fechaLlegada)){
				elOtroVuelo.setAerolinea(this.nombreAerolinea);
				retVal.add(elOtroVuelo);
			}
		}
 		
		return retVal;
	}
	
		
	public String[] parsearAsientoDTOAVuelo(AsientoDTO unAsiento){
		String fechaSalida = unAsiento.getFechaDeSalida();
		String fechaLlegada = unAsiento.getFechaDeLlegada();
		String horaSalida = unAsiento.getHoraDeSalida();
		String horaLlegada = unAsiento.getHoraDeLlegada();
		String precio = (unAsiento.getPrecio()).toString();
		String clase = unAsiento.getClase().toUpperCase().substring(0, 1);
		String ubicacion = unAsiento.getUbicacion().toUpperCase().substring(0, 1);
		String origen = unAsiento.getOrigen();
		String destino = unAsiento.getDestino();
		String codigoVuelo = unAsiento.getCodigoDeVuelo();
		String estado = "D";
		Boolean estadoPrevio = true;
		try{
			estadoPrevio = aerolinea.estaReservado(codigoVuelo, unAsiento.getNumeroDeAsiento());
		}catch (NullPointerException e){
			estado = "D";
		}
		if(estadoPrevio){
			estado = "R";
		}
		String numeroAsiento = Integer.toString(unAsiento.getNumeroDeAsiento());
		String codigo = codigoVuelo+"-"+numeroAsiento;
		String[] unVuelo = {codigo, precio, clase, ubicacion, estado, null, horaSalida, horaLlegada, origen, destino, fechaSalida, fechaLlegada};
		return unVuelo;
	}
	

	private void setParserLugar(){
		Collection<EstrategiaLugar> estrategias = new ArrayList<EstrategiaLugar>();
		EstrategiaDosLetras estrategiaDosLetras = new EstrategiaDosLetras();
		EstrategiaFormatoOk estrategiaFormatoOk = new EstrategiaFormatoOk();
		EstrategiaLA		estrategiaLA	    = new EstrategiaLA();
		estrategias.add(estrategiaLA);
		estrategias.add(estrategiaDosLetras);
		estrategias.add(estrategiaFormatoOk);
				
		this.parserEstrategiaLugar = new EstrategiaLugarFlexible(estrategias);
	}
}